//******************************************************************************
//  NGC
//
//  Description: Oxygen Conserver Software, based on SP209
//	Hardware to run on: Conserver PCB 081126-11 R2R0
//
//  A. Norman
//  ARware.com
//  September 2009
//
//
//	Version control:
//	0.0.a Initial Prototype Release
//
//******************************************************************************

#include "msp430x21x2.h"
const char string1[] = { "\r\nWhy did you hit the space bar?\r\n" };
const char *title = "\fINOVO New Generation Conserver\r\n"
					"Don't hold your breath...\r\n"
					"ARware.com MMIX\r\n"
					"\r\n"
					"switch position  ";
const char *V_Open = { "\r\n> Valve Open \r\n" };
const char *V_Close = { "\r\n> Valve Closed \r\n" };
const char *HV_OFF = { "\r\n> HV OFF \r\n" };
const char *autoP = { "\r\n> auto Pulse \r\n" };
const char *manuP = { "\r\n> manual Pulse with 'o' & 'c' \r\n" };
char CHRG_ON;
int bolus;
char a,
	b,
	c,
	d,
	s1,
	RxBuff;
int i,j,t,delay;

void send_char(const char *msg);

void send_char(const char *msg) {
	while(*msg != 0x00)	{
  		while ((IFG2 & UCA0TXIFG) != UCA0TXIFG);  // USART0 TX buffer ready?
  		UCA0TXBUF = *msg++;				// increment pointer to next character
  	}
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer0_A1(void) {
	switch (__even_in_range(TAIV, 10)) {  // Efficient switch-implementation
	case  2:  break;                    // TACCR1 not used
	case  4:  break;                    // TACCR2 not used
	case 10: {							// overflow
//openn routine
		P3OUT |= 0x04;					// flipping VON for scope sync
		P3OUT |= 0x02;
		for (delay = 0x0444; delay > 0; delay--);
		P3OUT &= ~0x02;
		send_char(V_Open);
// test bolus size 
		for (delay = bolus; delay > 0; delay--);
//close routine
		P2OUT |= 0x04;
		for (delay = 0x0444; delay > 0; delay--);
		P2OUT &= ~0x04;
		send_char(V_Close);
		P3OUT &= ~0x04;					// flipping VON for scope sync
		break;
		}
	}
}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void) {
	if ((P1IN & 0x08) != 0x08) {
		P1IES &= ~0x08;
	}	else {
		P1IES |= 0x08;
	}
	s1 = 1;
	for (delay = 0x1000; delay > 0; delay--);
	P1IFG &= ~0x08;						// P1.3 IFG cleared
}
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void) {
	volatile char IRQsrc;
	IRQsrc = P2IFG & 0x22;					// Mask for P2.1 and P2.5
	if ((IRQsrc & 0x20) == 0x20) {			// Checking P2.5
		if ((P2IN & 0x20) == 0x20) {		// The Pump is charged
			P2SEL &= ~0x01;					// Turn Charger Off 
			P2IES |= 0x20;					// Wait for discharge
		}	else {							// The Pump is discharged
			P2SEL |= 0x01;					// Turn Charger On
			P2IES &= ~0x20;					// Wait for charge up
		}
		P2IFG &= ~0x20;                           // P2.5 IFG cleared
	}
	if ((IRQsrc & 0x02) == 0x02) {			// Checking P2.1 
	//openn routine
		P3OUT |= 0x04;						// flipping VON for scope sync
		P3OUT |= 0x02;
		for (delay = 0x0444; delay > 0; delay--);
		P3OUT &= ~0x02;
		send_char(V_Open);
	// test bolus size 
		for (delay = bolus; delay > 0; delay--);
	//close routine
		P2OUT |= 0x04;
		for (delay = 0x0444; delay > 0; delay--);
		P2OUT &= ~0x04;
		send_char(V_Close);
		P3OUT &= ~0x04;						// flipping VON for scope sync
		P2IFG &= ~0x02;                           // P2.1 IFG cleared
	}
}

#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void) {
	UCA0TXBUF = string1[t++];			// TX next character
	if (t == sizeof string1 - 1)		// TX over?
	IE2 &= ~UCA0TXIE;					// Disable USCI_A0 TX interrupt
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) {
	if (UCA0RXBUF == ' ') {				// ' ' received?
		t = 0;
		IE2 |= UCA0TXIE;				// Enable USCI_A0 TX interrupt
		UCA0TXBUF = string1[t++];
	}
	RxBuff = UCA0RXBUF;
}


int main(void) {
	WDTCTL = WDTPW + WDTHOLD;
// P1 Init
	P1DIR = 0xD1;						// P1.0,.4,.6,.7-OUT; .1,.2,.3,.5-INPUT
	P1REN = 0x2E;						// P1.1,.2,.3,.5-Pullup
	P1OUT = 0x2E;						// P1.1,.2,.3,.5-Pullup
	P1SEL = 0x00;
//	P1IES = 0x08;						// P1.3 Hi/lo edge !Move below!
	P1IE = 0x08;						// P1.3 interrupt enabled
	P1IFG &= ~0x08;						// P1.3 IFG cleared

// P2 Init
	P2DIR |= 0x05;						// P2 .0,.2-OUT; .1,.3,.4,.5-INPUT
	P2REN |= 0x02;						// P2.1- Pullup
	P2OUT |= 0x02;						// P2.1- Pullup
	P2SEL &= ~0x22;						// P2.1,.5 I/O
	P2IES &= ~0x20;						// P2.5 Int. edge 0>1
	P2IES |= 0x02;						// P2.1 Int. edge 1>0
	P2IE |= 0x22;						// P2.1,.5 Interrupt Enabled
	P2IFG &= ~0x22;						// P2.1,.5 IFG cleared

// P3 Init
	P3DIR = 0x16;						// P3.1,.2,.4-OUT; .0,.3,.5,.6,.7-IN
	P3REN |= 0xE8;						// P3.3,.5,.6,.7-Pullup 
	P3OUT = 0x00;						// Clear out buffer
	P3SEL = 0x30;						// Set asynch serial port TX/RX

// UART Init
	UCA0CTL1 |= UCSSEL_1;				// CLK = ACLK
	UCA0BR0 = 0x03;						// 32kHz/9600 = 3.41
	UCA0BR1 = 0x00;						//
	UCA0MCTL = UCBRS1 + UCBRS0;			// Modulation UCBRSx = 3
	UCA0CTL1 &= ~UCSWRST;				// **Initialize USCI state machine**
	IE2 |= UCA0RXIE;					// Enable USCI_A0 RX interrupt

// Timer A Init
//	TACTL = TASSEL_1 + MC_1 + TAIE;		// ACLK, contmode, interrupt
	TACTL = TASSEL_1 + MC_1;			// ACLK, contmode, interrupt
	TACCR0 = 0xC000;

//	Initial charge of HV pump
	P2OUT &= ~0x04;						// Set PVOFF = 0
	P3OUT &= ~0x02;						// Set PVON = 0
	P2SEL |= 0x01;						// P2.0 32KHz ON

	__bis_SR_register(GIE);				// interrupts enabled

	send_char(title);


	j = P1IN & 0x0E;
	j ^= 0x0E;
	a = j << 2;
	b = j >> 2;
	c = a | b;
	c &= 0x0A;
	j &= 0x04;
	d = j | c;
	d = d >> 1;
	s1 = 0;

	UCA0TXBUF = d + 0x30;


for (;;) {
	
if (s1 != 0){
	j = P1IN & 0x0E;
	j ^= 0x0E;
	a = j << 2;
	b = j >> 2;
	c = a | b;
	c &= 0x0A;
	j &= 0x04;
	d = j | c;
	d = d >> 1;
	s1 = 0;
//	UCA0TXBUF = d + 0x30;
	bolus = (d * 0x0A66) + 0x14CC;
}

switch (RxBuff) {
	case 'o': {
		P3OUT |= 0x02;
		for (delay = 0x0444; delay > 0; delay--);
		P3OUT &= ~0x02;
		send_char(V_Open);
		break;
	}
	case 'c': {
		P2OUT |= 0x04;
		for (delay = 0x0444; delay > 0; delay--);
		P2OUT &= ~0x04;
		send_char(V_Close);
		break;
	}
	case '0': {
		P2SEL &= ~0x01;
		send_char(HV_OFF);
		break;
	}
	case 'a': {					// auto pulse
		TACCR0 = 0xFF00;		// Test breathing rate auto pulse
		TACTL |= TAIE;			// ACLK, contmode, interrupt
		send_char(autoP);
		break;
	}
	case 'm': {					// auto pulse
		TACTL &= ~TAIE;			// ACLK, contmode, interrupt
		send_char(manuP);
		break;
	}
}
RxBuff = 0x00;

} //for loop clouser

} //main clouser
